﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using SSHTool.Core.Message;
using SSHTool.Model;
using SSHTool.Service;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Controls;

namespace SSHTool.ViewModel
{
    public class MainViewModel : ObservableObject
    {
        private PageService pageService;
        private ConnectionService connectionService;
        private AuthService authService;
        public MainViewModel(ConnectionService connectionService, PageService pageService, AuthService authService)
        {
            this.connectionService = connectionService;
            this.pageService = pageService;
            this.authService = authService;
        }

        private string _title;
        private int _tabCurrentIndex;

        public string Title { get => _title; set => SetProperty(ref _title, value); }
        public int TabCurrentIndex { get => _tabCurrentIndex; set => SetProperty(ref _tabCurrentIndex, value); }

        private NavItemViewModel _currentNavItem;

        public NavItemViewModel CurrentNavItem { get => _currentNavItem; set => SetProperty(ref _currentNavItem, value); }

        private ObservableCollection<ConnectionViewModel> _menuList;

        public ObservableCollection<ConnectionViewModel> MenuList { get => _menuList; set => SetProperty(ref _menuList, value); }

        private ObservableCollection<NavItemViewModel> _tabMenuItems;

        public ObservableCollection<NavItemViewModel> TabMenuItemList
        {
            get => _tabMenuItems;
            set => SetProperty(ref _tabMenuItems, value);
        }

        public RelayCommand<SelectionChangedEventArgs> SwitchTabCmd => new RelayCommand<SelectionChangedEventArgs>(SwitchTab);

        public void Load()
        {
            RegisterMsg();

            Title = $"{Constant.APP_NAME} {Constant.APP_VERSION} [{authService.GetAuthText()}]";

            TabMenuItemList = new ObservableCollection<NavItemViewModel>();
            MenuList = connectionService.GetViewList<ConnectionModel, ConnectionViewModel>();
        }

        private void RegisterMsg()
        {
            WeakReferenceMessenger.Default.Register<NewTabItemMessage>(this, (r, m) =>
            {
                SwitchTabPage(m.Value, m.Connection);
            });

            WeakReferenceMessenger.Default.Register<NewMsgOutputMessage>(this, (r, m) =>
            {
                AppendText(m.Code, m.Value);
            });
        }

        private void SwitchTab(SelectionChangedEventArgs e)
        {
            if (e.RemovedItems.Count < 1)
            {
                return;
            }

            foreach (var item in e.RemovedItems)
            {
                if (item is NavItemViewModel model)
                {
                    Disconnect(model.Code);
                }
            }
        }

        private void SwitchTabPage(NavItemViewModel viewModel, ConnectionViewModel connection)
        {
            var item = _tabMenuItems.FirstOrDefault(m => m.Code == viewModel.Code);
            if (item != null)
            {
                CurrentNavItem = item;

                TabCurrentIndex = _tabMenuItems.IndexOf(item);
            }
            else
            {
                string code = Constant.CMD_PAGE_NAME;
                var page = pageService.CreatePage(code);

                if (page == null) return;

                if (page is Page content)
                {
                    var vm = pageService.GetService<CmdViewModel>();

                    vm.SetCode(viewModel.Code);
                    vm.Connection = connection;

                    content.DataContext = vm;
                    viewModel.Content = content;

                    CurrentNavItem = viewModel;

                    TabMenuItemList.Add(viewModel);
                    TabCurrentIndex = TabMenuItemList.Count - 1;

                    vm.Init();
                }
            }
        }

        private void AppendText(string code, string text)
        {
            var item = _tabMenuItems.FirstOrDefault(m => m.Code == code);
            if (item != null)
            {
                var page = item.Content;

                if (page.DataContext is CmdViewModel viewModel)
                {
                    viewModel.SetText(text);
                }
            }
        }

        private void Disconnect(string code)
        {
            var item = _tabMenuItems.FirstOrDefault(m => m.Code == code);
            if (item != null)
            {
                var page = item.Content;

                if (page.DataContext is CmdViewModel viewModel)
                {
                    viewModel.Disconnect();
                }
            }
        }

        #region 操作

        private bool shutDownApp = false;

        public bool ShutDownApp { get => shutDownApp; set => shutDownApp = value; }

        public RelayCommand ExitCmd => new RelayCommand(Exit);

        private void Exit()
        {
            ShutDownApp = true;

            Environment.Exit(0);
        }

        #endregion
    }
}
